﻿Imports System.IO
Imports System.Runtime.InteropServices

Public Class frmMain
    Dim dtTickTime As Date
    Dim CurrentProfile As String = ""
    Dim blnTimerSuspended As Boolean = False

    Private Sub frmMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        lblVersion.Text = My.Application.Info.Version.Major.ToString & "." & My.Application.Info.Version.Minor.ToString & "." & My.Application.Info.Version.Build.ToString
        For i As Integer = 1 To 30
            cbxSaveInterval.Items.Add(i)
        Next
        For i As Integer = 1 To 30
            cbxSaveMax.Items.Add(i)
        Next

        If My.Settings.SaveLocation = "" Then
            'try to find the steam path
            Dim pFilePath As String = "Program Files"
            If Directory.Exists("C:\Program Files (x86)") Then pFilePath = "Program Files (x86)"
            Dim s1 As String = "C:\" & pFilePath & "\Steam\userdata\"
            If Directory.Exists(s1) Then
                Dim d1 As String() = Directory.GetDirectories(s1)
                If d1.Count > 0 Then
                    'look in each folder for the userdata
                    For Each s As String In d1
                        If Directory.Exists(s & "\241540\local") Then
                            'pick this as the folder for saves
                            My.Settings.SaveLocation = s & "\241540\local"
                        End If
                    Next
                End If
            End If
        End If

        'if the folder for the save location didn't exist, force user to select it
        If My.Settings.SaveLocation = "" Then
            btnSaveLocation.PerformClick()
        End If

        'populate the profiles list
        ProfileRefreshList()

        cbxSaveInterval.SelectedItem = My.Settings.SaveInterval
        cbxSaveMax.SelectedItem = My.Settings.MaxSaves
        txbSaveLocation.Text = My.Settings.SaveLocation

        hookID = SetHook(proc)

        tmrSave.Interval = My.Settings.SaveInterval * 60 * 1000

        'Hotkey.RegisterHotKey(Me, 1, Keys.F5, Hotkey.KeyModifier.None)
        'Hotkey.RegisterHotKey(Me, 2, Keys.F9, Hotkey.KeyModifier.None)
    End Sub

    Private Sub btnSaveLocation_Click(sender As System.Object, e As System.EventArgs) Handles btnSaveLocation.Click
        If My.Settings.SaveLocation <> "" Then fbdSaveLocation.SelectedPath = My.Settings.SaveLocation
        fbdSaveLocation.ShowDialog()
        txbSaveLocation.Text = fbdSaveLocation.SelectedPath
        My.Settings.SaveLocation = fbdSaveLocation.SelectedPath
        tmrSave.Enabled = False
    End Sub

    Private Sub cbxSaveInterval_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cbxSaveInterval.SelectedIndexChanged
        My.Settings.SaveInterval = cbxSaveInterval.SelectedItem
        tmrSave.Enabled = False
        tmrSave.Interval = My.Settings.SaveInterval * 60 * 1000
    End Sub

    Private Sub cbxSaveMax_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cbxSaveMax.SelectedIndexChanged
        My.Settings.MaxSaves = cbxSaveMax.SelectedItem
        tmrSave.Enabled = False
    End Sub

    Private Sub btnRefresh_Click(sender As System.Object, e As System.EventArgs) Handles btnRefresh.Click
        RefreshListView()
    End Sub

    Private Sub btnRestore_Click(sender As System.Object, e As System.EventArgs) Handles btnRestore.Click
        PerformRestore(ListView1.SelectedItems(0).Text)
    End Sub

    Private Sub btnProfileAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnProfileAdd.Click
        ProfileAdd()
        ProfileRefreshList()
    End Sub

    Private Sub btnProfileDelete_Click(sender As System.Object, e As System.EventArgs) Handles btnProfileDelete.Click
        ProfileDelete(CurrentProfile)
    End Sub

    Private Sub btnProfileCopy_Click(sender As System.Object, e As System.EventArgs) Handles btnProfileCopy.Click
        ProfileCopy(CurrentProfile)
    End Sub

    Private Sub cbxProfile_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cbxProfile.SelectedIndexChanged
        Try
            'check to see that the current save point matches one of the existing profiles, if it doesn't then warn the user that the existing save will be overwritten
            Dim strPath As String = My.Settings.SaveLocation & "\" & cbxProfile.SelectedItem & ".profile"
            Dim blnPaths As Boolean = ComparePaths(My.Settings.SaveLocation, strPath)
            If blnPaths Then
                Dim blnMatch As Boolean = False
                'see if the files match any other profile
                Dim strProfiles As String() = GetProfiles(My.Settings.SaveLocation)
                For Each s As String In strProfiles
                    Dim strCurrPath As String = My.Settings.SaveLocation & "\" & s & ".profile"
                    blnMatch = ComparePaths(My.Settings.SaveLocation, strCurrPath)
                    If Not blnMatch Then
                        Exit For
                    End If
                Next

                If blnMatch Then
                    If MsgBox("Profile save does not match current game save. Do you wish to overwrite the current game save with profile save?", MsgBoxStyle.YesNo, "Save Game Mismatch") = MsgBoxResult.Yes Then
                        'overwrite the current save game with the profile current save
                        CopyFilesFromPath(strPath, My.Settings.SaveLocation)
                    Else
                        If MsgBox("If you continue to use the current save game with this profile, it will overwrite your profile current save. Are you sure you want to do this?", MsgBoxStyle.YesNo, "Warning") = MsgBoxResult.No Then
                            fswSync.EnableRaisingEvents = False
                            Exit Sub
                        Else
                            CopyFilesFromPath(My.Settings.SaveLocation, strPath)
                        End If
                    End If
                Else
                    'this fires if there is a match to the current save path, meaning the files won't be lost on a change of profile
                    CopyFilesFromPath(strPath, My.Settings.SaveLocation)
                End If
            End If
            My.Settings.Profile = cbxProfile.SelectedItem
            CurrentProfile = cbxProfile.SelectedItem
            RefreshListView()
            fswSync.Path = My.Settings.SaveLocation
            fswSync.EnableRaisingEvents = True
        Catch ex As Exception

        End Try

    End Sub

    Private Sub fswSync_Changed(sender As System.Object, e As System.IO.FileSystemEventArgs) Handles fswSync.Changed
        Dim complete As Boolean = False
        Do Until complete
            Try
                If File.Exists(e.FullPath) Then
                    File.Copy(e.FullPath, My.Settings.SaveLocation & "\" & CurrentProfile & ".profile\" & e.Name, True)
                End If
                complete = True
            Catch ex As Exception
                Threading.Thread.Sleep(1000)
            End Try
        Loop
    End Sub

    'Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    '    If m.Msg = Hotkey.WM_HOTKEY Then
    '        'Hotkey.handleHotKeyEvent(m.WParam)
    '    End If
    '    MyBase.WndProc(m)
    'End Sub

#Region "[   Subs / Functions  ]"
    Private Function GetProfiles(strPath As String) As String()
        Try
            If VerifySaveLocation() Then
                Dim strProfiles As String() = {}
                For Each s As String In Directory.GetDirectories(My.Settings.SaveLocation)
                    Dim strPaths As String() = Split(Path.GetFullPath(s), "\")
                    Dim sPath As String = strPaths(strPaths.Length - 1)
                    If Split(s, ".").Count > 1 Then
                        Dim aPath As String() = Split(sPath, ".")
                        If aPath(aPath.Length - 1) = "profile" Then
                            ReDim Preserve strProfiles(strProfiles.Length)
                            strProfiles(strProfiles.Length - 1) = aPath(0)
                        End If
                    End If
                Next
                Return strProfiles
            End If
            Return Nothing
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    Private Sub CopyFilesFromPath(strSourcePath As String, strDestPath As String)
        For Each s As String In Directory.GetFiles(strSourcePath)
            Dim FileName As String = Path.GetFileName(s)
            File.Copy(s, strDestPath & "\" & FileName, True)
        Next
    End Sub

    Public Sub PerformRestore(RestoreName)
        If Not bwpRestore.IsBusy Then
            bwpRestore.RunWorkerAsync(RestoreName)
        End If
    End Sub

    Private Function ComparePaths(strPath1 As String, strPath2 As String) As Boolean
        'true means there is a file that does NOT match
        Dim blnSave As Boolean = True
        For Each s As String In Directory.GetFiles(strPath1)
            'make sure the file exists
            If File.Exists(strPath2 & "\" & Path.GetFileName(s)) Then
                Dim oldInfo As FileInfo = New FileInfo(s)
                Dim newInfo As FileInfo = New FileInfo(strPath2 & "\" & Path.GetFileName(s))
                If oldInfo.LastWriteTime = newInfo.LastWriteTime Then
                    blnSave = False
                Else
                    blnSave = True
                    Exit For
                End If
            End If
        Next

        Return blnSave
    End Function

    Private Function VerifySaveLocation() As Boolean
        If Directory.Exists(My.Settings.SaveLocation) Then
            Return True
        Else
            MsgBox("Please set the location of the save game path. This is usually under your Program Files (or ""Program Files (x86)"" folder) under Steam\userdata\[profile number]\241540\local" & _
                   vbNewLine & vbNewLine & "This option must be set to continue.", MsgBoxStyle.Exclamation, "Invalid Save Path")
            Return False
        End If
    End Function

    Public Sub PerformBackup(SaveName As String)
        If Not bwpBackup.IsBusy Then
            bwpBackup.RunWorkerAsync(SaveName)
        End If
    End Sub

    Private Sub RefreshListView()
        If VerifySaveLocation() Then
            ListView1.Items.Clear()
            Dim PathName As String = My.Settings.SaveLocation & "\" & CurrentProfile & ".profile"
            If Not Directory.Exists(PathName) Then Directory.CreateDirectory(PathName)
            For Each s As String In Directory.GetDirectories(PathName)
                Dim strPath As String() = Split(s, "\")
                Dim strFolder As String = strPath(strPath.Length - 1)
                Dim dirInfo As DirectoryInfo = New DirectoryInfo(s)
                If s.Contains("backup") Then
                    Dim lItem As ListViewItem = New ListViewItem(strFolder)
                    lItem.Tag = s
                    lItem.SubItems.Add(dirInfo.LastWriteTime)
                    ListView1.Items.Add(lItem)
                ElseIf strFolder = "quick" Then
                    Dim lItem As ListViewItem = New ListViewItem(strFolder)
                    lItem.Tag = s
                    lItem.SubItems.Add(dirInfo.LastWriteTime)
                    ListView1.Items.Add(lItem)
                End If
            Next
        End If
    End Sub

    Private Sub ProfileRefreshList()
        If VerifySaveLocation() Then
            cbxProfile.Items.Clear()
            For Each s As String In Directory.GetDirectories(My.Settings.SaveLocation)
                Dim strPath As String() = Split(Path.GetFullPath(s), "\")
                Dim sPath As String = strPath(strPath.Length - 1)
                If Split(s, ".").Count > 1 Then
                    Dim aPath As String() = Split(sPath, ".")
                    If aPath(aPath.Length - 1) = "profile" Then
                        cbxProfile.Items.Add(aPath(0))
                    End If
                End If
            Next
            For Each s As String In cbxProfile.Items
                If s = My.Settings.Profile Then
                    cbxProfile.SelectedItem = My.Settings.Profile
                End If
            Next
            cbxProfile.SelectedItem = My.Settings.Profile
        End If
    End Sub

    Private Sub ProfileAdd()
        If VerifySaveLocation() Then
            Dim s As String = InputBox("Profile name", "Input new profile name", "default")
            If s = "" Then Exit Sub
            'check to see if this profile already exists
            Dim strDir As String = My.Settings.SaveLocation & "\" & s & ".profile"
            If Directory.Exists(strDir) Then
                If MsgBox("Profile " & s & " exists. Do you wish to overwrite?", MsgBoxStyle.YesNo, "Profile Exists") = MsgBoxResult.No Then Exit Sub
                Directory.Delete(strDir, True)
            End If

            Directory.CreateDirectory(strDir)
            CopyFilesFromPath(My.Settings.SaveLocation, strDir)
            My.Settings.Profile = s
            CurrentProfile = s
        End If
    End Sub

    Private Sub ProfileDelete(ByVal strProfile As String)
        If VerifySaveLocation() Then
            Dim strDir As String = My.Settings.SaveLocation & "\" & strProfile & ".profile"
            If Directory.Exists(strDir) Then
                If MsgBox("Delete " & strProfile & " and all saves for this profile?", MsgBoxStyle.YesNo, "Remove profile") = MsgBoxResult.Yes Then
                    Directory.Delete(strDir, True)
                End If
            End If
        End If
    End Sub

    Private Sub ProfileCopy(ByRef strProfile As String)
        If VerifySaveLocation() Then
            Dim s As String = InputBox("Profile name", "Input new profile name", "default")
            Dim strDir As String = My.Settings.SaveLocation & "\" & strProfile & ".profile"
            Dim strCopy As String = My.Settings.SaveLocation & "\" & s & ".profile"
            If Directory.Exists(strDir) And s <> "" Then
                If Directory.Exists(strCopy) Then
                    If MsgBox("Profile " & s & " exists. Do you wish to overwrite?", MsgBoxStyle.YesNo, "Profile Exists") = MsgBoxResult.No Then Exit Sub
                    Directory.Delete(strCopy, True)
                    Directory.CreateDirectory(strCopy)
                End If
                My.Computer.FileSystem.CopyDirectory(strDir, strCopy, True)
                CopyFilesFromPath(strDir, strCopy)
            End If
        End If
    End Sub
#End Region


#Region "[   Timer Functions  ]"
    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles tmrSave.Tick
        'save the game into backup
        PerformBackup("backup")
        dtTickTime = DateAdd(DateInterval.Minute, My.Settings.SaveInterval, Now)
        RefreshListView()
    End Sub

    Private Sub tmrMaintenance_Tick(sender As System.Object, e As System.EventArgs) Handles tmrMaintenance.Tick
        'if everything looks good, enable the timer and set the interval
        If My.Settings.SaveInterval > 0 And Directory.Exists(My.Settings.SaveLocation) And My.Settings.MaxSaves > 0 And Not blnTimerSuspended Then
            If Not tmrSave.Enabled Then
                tmrSave.Enabled = False
                tmrSave.Enabled = True
                dtTickTime = DateAdd(DateInterval.Minute, My.Settings.SaveInterval, Now)
            End If
            Dim timeLeft As Integer = DateDiff(DateInterval.Minute, Now, dtTickTime)
            lblTimerStatus.Text = "ACTIVE" & vbNewLine & timeLeft & "m TO" & vbNewLine & "NEXT SAVE"
            lblTimerStatus.BackColor = Color.LawnGreen
        Else
            tmrSave.Enabled = False
            lblTimerStatus.Text = "INACTIVE"
            lblTimerStatus.BackColor = Color.Red
        End If

        If ListView1.SelectedItems.Count > 0 Then
            btnRestore.Enabled = True
        Else
            btnRestore.Enabled = False
        End If

        If tmrSave.Enabled Then
            btnTimerEnable.Text = "Stop"
        Else
            btnTimerEnable.Text = "Start"
        End If
    End Sub
#End Region

    Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnSave.Click
        PerformBackup("backup")
    End Sub

#Region "[   Hooks   ]"

   
#End Region

    'Public Class Clip_Tray

    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const WM_KEYUP As Integer = &H101
    Private Const WM_SYSKEYUP As Integer = &H105
    Private proc As LowLevelKeyboardProcDelegate = AddressOf HookCallback
    Private hookID As IntPtr

    Private Delegate Function LowLevelKeyboardProcDelegate(ByVal nCode As Integer, ByVal wParam As IntPtr, _
        ByVal lParam As IntPtr) As IntPtr

    <DllImport("user32")> _
    Private Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal lpfn As LowLevelKeyboardProcDelegate, _
        ByVal hMod As IntPtr, ByVal dwThreadId As UInteger) As IntPtr
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function UnhookWindowsHookEx(ByVal hhk As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function

    <DllImport("user32.dll")> _
    Private Shared Function CallNextHookEx(ByVal hhk As IntPtr, ByVal nCode As Integer, ByVal wParam As IntPtr, _
        ByVal lParam As IntPtr) As IntPtr
    End Function

    <DllImport("kernel32.dll", CharSet:=CharSet.Unicode)> _
    Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
    End Function

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
        UnhookWindowsHookEx(hookID)
    End Sub

    Private Function SetHook(ByVal proc As LowLevelKeyboardProcDelegate) As IntPtr
        Using curProcess As Process = Process.GetCurrentProcess()
            Using curModule As ProcessModule = curProcess.MainModule
                Return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0)
            End Using
        End Using
    End Function

    Private Function HookCallback(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        ' "The WM_KEYUP message is posted to the window with the keyboard focus
        ' when a nonsystem key is released. A nonsystem key is a key that is pressed when the ALT key is not pressed,
        ' or a keyboard key that is pressed when a window has the keyboard focus." 
        If nCode >= 0 AndAlso (wParam.ToInt32 = WM_KEYUP OrElse wParam.ToInt32 = WM_SYSKEYUP) Then
            Dim vkCode As Integer = Marshal.ReadInt32(lParam)
            Select Case vkCode
                Case Keys.F5
                    PerformBackup("quick")
                Case Keys.F9
                    PerformRestore("quick")

            End Select
        End If
        Return CallNextHookEx(hookID, nCode, wParam, lParam)
    End Function

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles btnTimerEnable.Click
        tmrSave.Enabled = Not tmrSave.Enabled
        blnTimerSuspended = Not tmrSave.Enabled
        tmrSave.Interval = My.Settings.SaveInterval * 60 * 1000
    End Sub

    Private Sub tmrHook_Tick(sender As System.Object, e As System.EventArgs) Handles tmrHook.Tick
        UnhookWindowsHookEx(hookID)
        hookID = SetHook(proc)
    End Sub

    Private Sub bwpBackup_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwpBackup.DoWork
        Dim SaveName As String = CStr(e.Argument)
        If SaveName = "" Then Exit Sub
        If Not VerifySaveLocation() Then Exit Sub
        Dim PathProfile As String = My.Settings.SaveLocation & "\" & CurrentProfile & ".profile"
        Dim PathName As String = My.Settings.SaveLocation & "\" & CurrentProfile & ".profile"
        If Not Directory.Exists(PathName) Then Directory.CreateDirectory(PathName)
        Dim strLastPath As String = ""
        Dim intBackups As Integer = 0
        Dim strOldest As String = ""

        If SaveName = "quick" Then
            If Directory.Exists(PathName & "\quick") Then Directory.Delete(PathName & "\quick", True)
            Directory.CreateDirectory(PathName & "\quick")
            PathName &= "\" & SaveName
            strLastPath = PathName
        Else
            PathName &= "\backup-" & Now.Year & "." & Format(Now.Month, "00") & "." & Format(Now.Day, "00") & "-" & Format(Now.Hour, "00") & "." & Format(Now.Minute, "00") & "." & Format(Now.Second, "00")

            'find the oldest path that exceeds the max count and delete it
            Dim dtOldest As Date = Now
            Dim dtNewest As Date = DateAdd(DateInterval.Year, -99, Now)

            Dim sPaths As String() = Directory.GetDirectories(PathProfile)

            For Each s As String In sPaths
                'check the date on the end, if it is older than the previous one, set the strOldest to the path location
                If s.Contains("backup") Then
                    intBackups += 1
                    Dim strPath As String() = Split(Path.GetFullPath(s), "\")
                    Dim strSplit As String() = Split(strPath(strPath.Length - 1), "-")
                    If strSplit.Count = 3 Then
                        Dim sDate As String() = Split(strSplit(1), ".")
                        Dim sTime As String() = Split(strSplit(2), ".")
                        Dim dtPath As Date = CDate(sDate(1) & "/" & sDate(2) & "/" & sDate(0) & " " & sTime(0) & ":" & sTime(1) & ":" & sTime(2))
                        If dtPath < dtOldest Then
                            dtOldest = dtPath
                            strOldest = s
                        End If
                        If dtPath > dtNewest Then
                            dtNewest = dtPath
                            strLastPath = s
                        End If
                    End If
                End If
            Next
        End If

        'compare the last path with the current path and make sure the files have changed. If not, don't make a new save
        Dim blnSave As Boolean = True
        If strLastPath <> "" Then
            blnSave = ComparePaths(My.Settings.SaveLocation, strLastPath)
            If Not blnSave Then Exit Sub
        End If

        If Not Directory.Exists(PathName) Then
            Directory.CreateDirectory(PathName)
        End If

        If intBackups > My.Settings.MaxSaves Then
            Directory.Delete(strOldest, True)
        End If

        For Each s As String In Directory.GetFiles(My.Settings.SaveLocation)
            File.Copy(s, PathName & "\" & Path.GetFileName(s), True)
        Next
    End Sub

    Private Sub bwpBackup_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwpBackup.RunWorkerCompleted
        RefreshListView()
    End Sub

    Private Sub bwpRestore_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwpRestore.DoWork
        Dim RestoreName As String = CStr(e.Argument)
        If RestoreName = "" Then Exit Sub
        If Not My.Settings.SaveLocation <> "" Then Exit Sub
        Dim PathName As String = My.Settings.SaveLocation & "\" & CurrentProfile & ".profile" & "\" & RestoreName
        If Not Directory.Exists(PathName) Then Directory.CreateDirectory(PathName)
        If Directory.Exists(PathName) Then
            If Not PathName.Contains("quick") Then If MsgBox("Do you wish to overwrite your current save game with save from " & RestoreName & "?", MsgBoxStyle.YesNo, "Restore Save Game") = MsgBoxResult.No Then Exit Sub
            CopyFilesFromPath(PathName, My.Settings.SaveLocation)
        End If
    End Sub
End Class

Public Class Hotkey

#Region "Declarations - WinAPI, Hotkey constant and Modifier Enum"
    ''' <summary>
    ''' Declaration of winAPI function wrappers. The winAPI functions are used to register / unregister a hotkey
    ''' </summary>
    Public Declare Function RegisterHotKey Lib "user32" _
    (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer

    Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer

    Public Const WM_HOTKEY As Integer = &H312

    Enum KeyModifier
        None = 0
        Alt = &H1
        Control = &H2
        Shift = &H4
        Winkey = &H8
    End Enum 'This enum is just to make it easier to call the registerHotKey function: The modifier integer codes are replaced by a friendly "Alt","Shift" etc.
#End Region

#Region "Hotkey registration, unregistration and handling"
    Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByRef HotKeyID As Integer, ByVal triggerKey As String, ByVal modifier As KeyModifier)
        RegisterHotKey(sourceForm.Handle, HotKeyID, modifier, Asc(triggerKey.ToUpper))
    End Sub

    Public Shared Sub registerHotkey(ByRef sourceForm As Form, ByRef HotKeyID As Integer, ByVal triggerKey As Integer, ByVal modifier As KeyModifier)
        RegisterHotKey(sourceForm.Handle, HotKeyID, modifier, triggerKey)
    End Sub

    Public Shared Sub unregisterHotkeys(ByRef sourceForm As Form, ByRef HotKeyID As Integer)
        UnregisterHotKey(sourceForm.Handle, HotKeyID)  'Remember to call unregisterHotkeys() when closing your application.
    End Sub
    Public Shared Sub handleHotKeyEvent(ByVal hotkeyID As IntPtr)
        Select Case hotkeyID
            Case 1
                frmMain.PerformBackup("quick")
            Case 2
                frmMain.PerformRestore("quick")
        End Select
    End Sub
#End Region

End Class







